package com.xh.demo.config.handler;

import cn.hutool.core.util.StrUtil;
import com.xh.demo.commons.enums.MessageEnum;
import com.xh.demo.commons.exception.BusinessException;
import com.xh.demo.commons.model.response.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import javax.servlet.http.HttpServletRequest;

/**
 * @author wen
 * @apiNote 全局异常处理器
 * @since 2021/12/11
 */
@Slf4j
//@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(BusinessException.class)
    public ResponseEntity<R<Void>> handleBusinessException(BusinessException ex, HttpServletRequest request) {
        log.error("【异常处理器-业务异常处理】【请求路径:{}】【错误码:{}】【错误信息:{}】", request.getRequestURI(), ex.getCode(), ex.getMsg());
        return ResponseEntity.ok().body(R.build(ex));
    }

    @ExceptionHandler(BindException.class)
    public ResponseEntity<R<Void>> handleBindException(BindException ex, HttpServletRequest request) {
        log.error("【异常处理器-参数不合法异常】【请求路径:{}】【错误信息:{}】", request.getRequestURI(), ex.getMessage());
        return ResponseEntity.ok().body(getBindingResult(ex.getBindingResult()));
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<R<Void>> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, HttpServletRequest request) {
        log.error("【异常处理器-参数不合法异常】【请求路径:{}】【错误信息:{}】", request.getRequestURI(), ex.getMessage());
        return ResponseEntity.ok().body(getBindingResult(ex.getBindingResult()));
    }

    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    public ResponseEntity<R<Void>> handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException ex, HttpServletRequest request) {
        log.error("【异常处理器-参数不合法异常】【请求路径:{}】【错误信息:{}】", request.getRequestURI(), ex.getMessage());
        return ResponseEntity.ok().body(R.build(MessageEnum.PARAMETER_VERIFICATION_ERROR));
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<R<Void>> handleException(Exception ex, HttpServletRequest request) {
        log.error("【异常处理器-系统处理异常】【请求路径:{}】【错误信息:{}】", request.getRequestURI(), ex);
        return ResponseEntity.ok().body(R.build(MessageEnum.REQUEST_LIMITED));
    }

    /**
     * 参数不合法处理结果
     */
    private R<Void> getBindingResult(BindingResult ex) {
        StringBuilder sb = new StringBuilder();
        ex.getAllErrors().forEach(t -> sb.append(t.getDefaultMessage()).append(StrUtil.COLON));
        return R.build(sb.toString(), MessageEnum.PARAMETER_VERIFICATION_ERROR);
    }
}
